package com.cdtu.outtake.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdtu.outtake.dao.OrderMapper;
import com.cdtu.outtake.domain.*;
import com.cdtu.outtake.MyException;
import com.cdtu.outtake.service.*;
import com.cdtu.outtake.domain.*;
import com.cdtu.outtake.domain.enums.OrderStatus;
import com.cdtu.outtake.dto.OrderDDto;
import com.cdtu.outtake.dto.OrderDto;
import com.cdtu.outtake.dto.ShopDto;
import com.cdtu.outtake.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author : shl
 * @Date 2024/4/6 12:27
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    private final StringRedisTemplate stringRedisTemplate;
    private final ICartService cartService;
    private final IUserService userService;
    private final IShopService shopService;
    private final ICommentService commentService;
    private final IAddressService addressService;

    @Override
    @Transactional
    public void createOrder(OrderPo orderPo) {
        ShopOfCart shopOfCart = cartService.getShopOfCart(orderPo.getShopId());
        Address address = addressService.getAddressById(orderPo.getAddressId());
        Order order = Order.builder()
                .status(OrderStatus.payed)
                .createTime(LocalDateTime.now())
                .deliverTime(shopService.getShopById(shopOfCart.getShopId()).getLat())
                .packageFees(shopOfCart.getAmountPackagePrice())
                .totalCost(shopOfCart.getAmountPrice()+shopOfCart.getAmountPackagePrice())
                .remark(orderPo.getRemark())
//                .cutleryNumber(shopOfCart.getCutleryNumber())
                .shopId(orderPo.getShopId())
                .sn(orderPo.getSn())
                .items(shopOfCart.getCartItems())
                .deliverer(orderPo.getPayMethod())
                .deliveryFees(0.00)
                .userName(address.getName())
                .userAd(address.getAd())
                .userPhone(address.getPhone())
                .userGender(address.getGender())
                .build();
//        Order order = orderVO.convertToOrder();
        //TODO 设置用户ID
        order.setUserId(userService.getMyUserId());
        if (this.baseMapper.insert(order) != 1) {
            throw new MyException("订单数据写入失败");
        }
        stringRedisTemplate.opsForValue().set("order:" + order.getId(), JSON.toJSONString(order));//order.getItems()
        //TODO 购物车数据加入缓存
        stringRedisTemplate.opsForValue().set("order-detail:" + order.getId(), JSON.toJSONString(order.getItems()));//order.getItems()
        cartService.clearCartOfShop(orderPo.getShopId());
    }


    //TODO 获取当前订单
    @Override
    public List<OrderDDto> getCurrentOrder() {
        List<Order> orderList =
                baseMapper.selectList(new QueryWrapper<Order>()
                        .in("status", List.of("payed"))
                        .eq("user_id", userService.getMyUserId()));
        if (null == orderList||orderList.isEmpty()) return null;
        return orderList.stream().sorted((a, b) -> a.getCreateTime().isAfter(b.getCreateTime()) ? -1 : 1).map(order -> {
                    String s = stringRedisTemplate.opsForValue().get("order:" + order.getId());
                    Order order1 = JSONUtil.toBean(s, Order.class);

//                    ShopDto shop = shopService.getShopDetailById(order1.getShopId()).getShop();
                    Long shopId = order1.getShopId();
                    Shop shop = shopService.getShopById(shopId);
                    OrderDDto orderDDto = new OrderDDto();
                    BeanUtil.copyProperties(order1, orderDDto);
                    orderDDto.setShopName(shop.getName());
                    return orderDDto;
                })
                .collect(Collectors.toList());
    }

/*
    @Override
    public OrderDDto makeOrder(Long shopId) {
        OrderDDto oddo=new OrderDDto();
        ShopOfCart shopOfCart = cartService.getShopOfCart(shopId);
        oddo.setItems(shopOfCart.getCartItems());
        oddo.setPackageFees(shopOfCart.getAmountPackagePrice());
        oddo.setDeliveryFees(0.00);
        oddo.setTotalCost(shopOfCart.getAmountPrice());
        oddo.setShopName(shopOfCart.getShopName());
        oddo.setDeliverer("在线方式");//TODO 支付方式写死了

        oddo.setUserAd(addressService.getDefaultAddressesByUserId(userService.getMyUserId()).toString());
        oddo.setUserGender(userService.getMyUserInfo().getGender());
        oddo.setUserPhone(userService.getMyUserInfo().getPhone());
        oddo.setSn("外卖");//TODO 就餐方式写死了

        oddo.setStatus(OrderStatus.created);
        return oddo;
    }
*/

    @Override
    public List<OrderDto> getOrdersByType(OrderType type) {
        List<Order> orderList;
        if (type == OrderType.all) {
            orderList = baseMapper.selectList(new QueryWrapper<Order>()
                    .eq("user_id", userService.getMyUserId()));
            //待使用（进行中）
        } else if (type == OrderType.received) {
            orderList = baseMapper.selectList(new QueryWrapper<Order>()
                    .in("status", List.of("created", "payed", "consented", "produced", "delivering", "delivered"))
                    .eq("user_id", userService.getMyUserId()));
            //待评价
        } else if (type == OrderType.used) {
            orderList = baseMapper.selectList(new QueryWrapper<Order>()
                            .in("status", List.of("received"))
                            .eq("user_id", userService.getMyUserId())).stream()
                    .filter(order -> !commentService.hasCommentByOrderId(order.getId()))
                    .collect(Collectors.toList());
            //退款/售后
        } else {
            orderList = baseMapper.selectList(new QueryWrapper<Order>()
                    .in("status", List.of("refunding", "refused", "refunded"))
                    .eq("user_id", userService.getMyUserId()));
        }
        return orderList.stream().sorted((a, b) -> a.getCreateTime().isAfter(b.getCreateTime()) ? -1 : 1).map(order -> {
                    ShopDto shop = shopService.getShopDetailById(order.getShopId()).getShop();
                    return OrderDto.builder()
                            .orderId(order.getId())
                            .shopId(shop.getId())
                            .shopName(shop.getName())
                            .status(OrderStatus.toChinese(order.getStatus()))
                            .createTime(order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                            .totalCost(order.getTotalCost())
                            .shopPicture(shop.getPicture())
                            .comment(commentService.hasCommentByOrderId(order.getId()))
                            .type(order.getSn())
                            .items(JSONUtil.toList(stringRedisTemplate.opsForValue().get("order-detail:" + order.getId()), CartItem.class))
                            .build();
                })
                .collect(Collectors.toList());
    }
}
